local extension = Package("joy_nzbz")
extension.extensionName = "joy"

Fk:loadTranslationTable{
  ["joy_nzbz"] = "欢乐-南征北战",
}

local U = require "packages/utility/utility"


local xushao = General(extension, "joy__xushao", "qun", 4)

local pingjian_skills = {
  -- 出牌阶段
  ["play"] =
  {
  "nya__lijian","nya__guose","nya__jieyi","joyex__lijian","joyex__duanliang","joy__shenglun","joyex__qiangxi",
  "joy__jueyan","joy__huairou","joy__qice","joy__kuangbi","joy__mingjian","joy__huoxin","joy__poxi","shencai","joy__yingba","ol__xuehen",
  "joy__yanxiao","joy__xingwu","joy__guolun","joysp__juesi","joy__lihun","joy_mou__kurou","xieju","duanfa","jiezhen","joy__mingjian",
  "ty__gushe","anzhi","zhuren","jinghe","jinhui","yuanyu","joy__wengua","kurou","joy__duwu","joy__anguo","joy__god_huishi","joy__zuoxing",
  "zhanhuo","joy__jianshu","zunwei","joysp__weikui","joy__manwang","joy__jixu","joy__xiaowu","joy__channi","joy__quanji","joy__paiyi",
  "ty__zhongjian","joy__weilie","joy__yanjiao","joyex__zhiheng","joyex__jieyi","joyex__wanrong","joyex__qixi","joy__xianzhu","joy__youyan",
  "limu","joy_mou__duojing","joy_mou__luanji","joyex__qingnang","joy_mou__duanliang","joy__difa","ty_ex__wurong","joyex__changbiao","joy_mou__qingzheng","joy__chenglue","joyex__wuchang","joy__mubing","joy__diaoling","joyex__rende","joy__lusu",
  --限定技，觉醒技
  "joy__wujian","nya__xianzhou","joyex__qimou","xiongluan","joy__shenfen","joy__pingxiang","ex__yongjin","mobile__limited_huishi","joy__yongbi",
  "joy__yongdi","joy_mou__zhangwu",
  },
  --受到伤害后 
  [fk.Damaged] =
  {
    --[[
    "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__guixin",
    "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","joy__chengxiang",
    "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi","joy__quanji","joy__jiushi",
    ]]
    "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__wuhun","joy__guixin",
        "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","junlue","joy__chengxiang",
        "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi",
  },
  --结束阶段
  [fk.EventPhaseStart] =
  {
    --[[
    "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
    "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen",
    "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan",
    ]]
    "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
        "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen","miji",
        "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan","joyex__jushou",
        --觉醒技，限定技
        "joy__wuji","joyex__qinxue",
  }
}

local getPingjianSkills = function (player, event)
  local used_skills = player:getTableMark( "joy__pingjian_used")
  local e = event and event or "play"
  return table.filter(pingjian_skills[e], function (skill_name)
    local sk = Fk.skills[skill_name]
    return sk and not table.contains(used_skills, skill_name) and not player:hasSkill(sk, true)
  end)
end

---@param player ServerPlayer
local addTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil or player:hasSkill(skill_name, true) then return false end
  room:handleAddLoseSkills(player, skill_name, nil)
  local skills = player:getTableMark( "joy__pingjian_skills")
  table.insertIfNeed(skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", skills)
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  table.insert(pingjian_skill_times, {skill_name, player:usedSkillTimes(skill_name)})
  for _, s in ipairs(skill.related_skills) do
    table.insert(pingjian_skill_times, {s.name, player:usedSkillTimes(s.name)})
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", pingjian_skill_times)
end

---@param player ServerPlayer
local removeTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil then return false end
  room:handleAddLoseSkills(player, "-" .. skill_name, nil)
  local skills = player:getTableMark( "joy__pingjian_skills")
  table.removeOne(skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", skills)
  local invoked = false
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  local record_copy = {}
  for _, pingjian_record in ipairs(pingjian_skill_times) do
    if #pingjian_record == 2 then
      local record_name = pingjian_record[1]
      if record_name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= record_name end) then
        if player:usedSkillTimes(record_name) > pingjian_record[2] then
          invoked = true
        end
      else
        table.insert(record_copy, pingjian_record)
      end
    end
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", record_copy)

  if invoked then
    local used_skills = player:getTableMark( "joy__pingjian_used")
    table.insertIfNeed(used_skills, skill_name)
    room:setPlayerMark(player, "joy__pingjian_used", used_skills)
  end
end

local joy__pingjian = fk.CreateActiveSkill{
  name = "joy__pingjian",
  prompt = "#joy__pingjian-active",
  card_num = 0,
  target_num = 0,
  card_filter = Util.FalseFunc,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local skills = getPingjianSkills(player)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, self.name, "#joy__pingjian-choice", true)
    local phase_event = room.logic:getCurrentEvent():findParent(GameEvent.Phase)
    if phase_event ~= nil then
      addTYPingjianSkill(player, skill_name)
      phase_event:addCleaner(function()
        removeTYPingjianSkill(player, skill_name)
      end)
    end
  end,
}
local joy__pingjian_trigger = fk.CreateTriggerSkill{
  name = "#joy__pingjian_trigger",
  events = {fk.Damaged, fk.EventPhaseStart},
  main_skill = joy__pingjian,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(joy__pingjian) or player ~= target then return false end
    if event == fk.Damaged then
      return true
    elseif event == fk.EventPhaseStart then
      return player.phase == Player.Finish
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, joy__pingjian.name)
    player:broadcastSkillInvoke(joy__pingjian.name)
    local skills = getPingjianSkills(player, event)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, joy__pingjian.name, "#joy__pingjian-choice", true)
    local skill = Fk.skills[skill_name]
    if skill == nil then return false end
    local _skill = skill
    if not _skill:isInstanceOf(TriggerSkill) then
      _skill = table.find(_skill.related_skills, function (s)
        return s:isInstanceOf(TriggerSkill)
      end)
      if not _skill then return end
    end

    addTYPingjianSkill(player, skill_name)
    if _skill:triggerable(event, target, player, data) then
      _skill:trigger(event, target, player, data)
    end
    removeTYPingjianSkill(player, skill_name)
  end,

  refresh_events = {fk.DamageInflicted},
  can_refresh = function(self, event, target, player, data)
    return target == player and not player.faceup
  end,
  on_refresh = function(self, event, target, player, data)
    data.extra_data = data.extra_data or {}
    data.extra_data.jiushi_check = true
  end,
}
local joy__pingjian_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__pingjian_invalidity",
  invalidity_func = function(self, player, skill)
    local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
    return table.find(pingjian_skill_times, function (pingjian_record)
      if #pingjian_record == 2 then
        local skill_name = pingjian_record[1]
        if skill.name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= skill_name end) then
            return player:usedSkillTimes(skill_name) > pingjian_record[2]
        end
      end
    end)
  end
}

joy__pingjian:addRelatedSkill(joy__pingjian_trigger)
joy__pingjian:addRelatedSkill(joy__pingjian_invalidity)
xushao:addSkill(joy__pingjian)

Fk:loadTranslationTable{
  ["joy__xushao"] = "许劭",
  ["#joy__xushao"] = "识人读心",
  
  ["joy__pingjian"] = "评荐",
  ["#joy__pingjian_trigger"] = "评荐",
  [":joy__pingjian"] = "出牌阶段，或结束阶段，或当你受到伤害后，你可以从对应时机的技能池中随机抽取三个技能，"..
    "然后你选择并视为拥有其中一个技能直到时机结束（每个技能限发动一次）。",
  ["#joy__pingjian-active"] = "评荐：从三个出牌阶段的技能中选择一个学习",
  ["#joy__pingjian-choice"] = "评荐：选择要学习的技能",

  ["$joy__pingjian1"] = "我乘青舟访人间，人如江鲫逐功名。",
  ["$joy__pingjian2"] = "一言难道千秋业 一纸雅评半世人。",
  ["~joy__xushao"] = "满纸辛酸荒唐泪,君当务实莫贪名！",
}
--[[
local xushao = General(extension, "joy__xushao", "qun", 4)

---@param player ServerPlayer
local addTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil or player:hasSkill(skill_name, true) then return false end
  room:handleAddLoseSkills(player, skill_name, nil)
  local pingjian_skills = player:getTableMark( "joy__pingjian_skills")
  table.insertIfNeed(pingjian_skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", pingjian_skills)
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  table.insert(pingjian_skill_times, {skill_name, player:usedSkillTimes(skill_name)})
  for _, s in ipairs(skill.related_skills) do
    table.insert(pingjian_skill_times, {s.name, player:usedSkillTimes(s.name)})
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", pingjian_skill_times)
end

---@param player ServerPlayer
local removeTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil then return false end
  room:handleAddLoseSkills(player, "-" .. skill_name, nil)
  local pingjian_skills = player:getTableMark( "joy__pingjian_skills")
  table.removeOne(pingjian_skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", pingjian_skills)
  local invoked = false
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  local record_copy = {}
  for _, pingjian_record in ipairs(pingjian_skill_times) do
    if #pingjian_record == 2 then
      local record_name = pingjian_record[1]
      if record_name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= record_name end) then
        if player:usedSkillTimes(record_name) > pingjian_record[2] then
          invoked = true
        end
      else
        table.insert(record_copy, pingjian_record)
      end
    end
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", record_copy)

  if invoked then
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    table.insertIfNeed(used_skills, skill_name)
    room:setPlayerMark(player, "joy__pingjian_used_skills", used_skills)
  end
end

local ty__pingjian = fk.CreateActiveSkill{
  name = "joy__pingjian",
  prompt = "#joy__pingjian-active",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:getMark("joy__pingjian-phase") == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    local skills = table.filter({
      "nya__lijian","nya__guose","nya__jieyi","joy__daoyao","joy__tuantu","joyex__lijian","joyex__duanliang","joy__shenglun","joyex__qiangxi",
      "joy__jueyan","joy__huairou","joy__qice","joy__kuangbi","joy__mingjian","joy__huoxin","joy__poxi","shencai","joy__yingba","ol__xuehen",
      "joy__yanxiao","joy__xingwu","joy__guolun","joysp__juesi","joy__lihun","joy_mou__kurou","xieju","duanfa","jiezhen","joy__mingjian",
      "ty__gushe","anzhi","zhuren","jinghe","jinhui","yuanyu","joy__wengua","kurou","joy__duwu","joy__anguo","joy__god_huishi","joy__zuoxing",
      "zhanhuo","joy__jianshu","zunwei","joysp__weikui","joy__manwang","joy__jixu","joy__xiaowu","joy__channi","joy__quanji","joy__paiyi",
      "ty__zhongjian","joy__weilie","joy__yanjiao","joyex__zhiheng","joyex__jieyi","joyex__wanrong","joyex__qixi","joy__xianzhu","joy__youyan",
      "limu","joy_mou__duojing","joy_mou__luanji","joyex__qingnang","joy_mou__duanliang","joy__difa","ty_ex__wurong","joyex__changbiao","joy_mou__qingzheng","joy__chenglue","joyex__wuchang",
      --限定技，觉醒技
      "joy__wujian","nya__xianzhou","joyex__qimou","xiongluan","joy__shenfen","joy__pingxiang","ex__yongjin","mobile__limited_huishi","joy__yongbi",
      "joy__yongdi","joy_mou__zhangwu",
    }, function (skill_name)
      return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
    end)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, self.name, "#joy__pingjian-choice", true)
    room:setPlayerMark(player,"joy__pingjian-phase",1)
    local phase_event = room.logic:getCurrentEvent():findParent(GameEvent.Phase)
    if phase_event ~= nil then
      addTYPingjianSkill(player, skill_name)
      phase_event:addCleaner(function()
        removeTYPingjianSkill(player, skill_name)
      end)
    end
  end,
}
local ty__pingjian_trigger = fk.CreateTriggerSkill{
  name = "#joy__pingjian_trigger",
  events = {fk.Damaged, fk.EventPhaseStart},
  main_skill = ty__pingjian,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(ty__pingjian.name) or player ~= target then return false end
    if event == fk.Damaged then
      return true
    elseif event == fk.EventPhaseStart then
      return player.phase == Player.Finish
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, ty__pingjian.name)
    player:broadcastSkillInvoke(ty__pingjian.name)
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    local skills = {}
    if event == fk.Damaged then
      skills = table.filter({
        "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__wuhun","joy__guixin",
        "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","junlue","joy__chengxiang",
        "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi",
      }, function (skill_name)
        return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
      end)
    elseif event == fk.EventPhaseStart then
      skills = table.filter({
        "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
        "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen","miji",
        "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan",
        --觉醒技，限定技
        "joy__wuji","joyex__qinxue",
      }, function (skill_name)
        return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
      end)
    end
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, ty__pingjian.name, "#joy__pingjian-choice", true)
    local skill = Fk.skills[skill_name]
    if skill == nil then return false end

    addTYPingjianSkill(player, skill_name)
    if skill:triggerable(event, target, player, data) then
      skill:trigger(event, target, player, data)
    end
    removeTYPingjianSkill(player, skill_name)
  end,
}
local ty__pingjian_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__pingjian_invalidity",
  invalidity_func = function(self, player, skill)
    local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
    return table.find(pingjian_skill_times, function (pingjian_record)
      if #pingjian_record == 2 then
        local skill_name = pingjian_record[1]
        if skill.name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= skill_name end) then
            return player:usedSkillTimes(skill_name) > pingjian_record[2]
        end
      end
    end)
  end
}

ty__pingjian:addRelatedSkill(ty__pingjian_trigger)
ty__pingjian:addRelatedSkill(ty__pingjian_invalidity)
xushao:addSkill(ty__pingjian)

Fk:loadTranslationTable{
  ["joy__xushao"] = "许劭",
  ["#joy__xushao"] = "食人毒心",

  ["joy__pingjian"] = "评荐",
  ["#joy__pingjian_trigger"] = "评荐",
  [":joy__pingjian"] = "出牌阶段，或结束阶段，或当你受到伤害后，你可以从对应时机的技能池中随机抽取三个技能，"..
    "然后你选择并视为拥有其中一个技能直到时机结束（每个技能限发动一次）。"..
    '<br /><font color="red">（村：欢杀包特色，只会获得欢杀池内武将的技能，没说不能拿的技能就是能拿）</font>',
  ["#joy__pingjian-active"] = "发动 评荐，从三个出牌阶段的技能中选择一个学习",
  ["#joy__pingjian-choice"] = "评荐：选择要学习的技能",

  ["$joy__pingjian1"] = "我乘青舟访人间，人如江鲫逐功名。",
  ["$joy__pingjian2"] = "一言难道千秋业 一纸雅评半世人。",
  ["~joy__xushao"] = "满纸辛酸荒唐泪,君当务实莫贪名！",

}]]

local joy__guansuo = General(extension, "joy__guansuo", "shu", 4)
local joy__zhengnan = fk.CreateTriggerSkill{
  name = "joy__zhengnan",
  anim_type = "drawcard",
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (player:getMark(self.name) == 0 or not table.contains(player:getMark(self.name), target.id))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark(self.name)
    local n = 0
      if target == player and player:hasSkill(self) then
        n = 1
      end
    if mark == 0 then mark = {} end
    table.insert(mark, target.id)
    room:setPlayerMark(player, self.name, mark)
    if player:isWounded() then
      room:recover({
        who = player,
        num = 1+n,
        recoverBy = player,
        skillName = self.name
      })
    end
    local choices = {"joy__wusheng", "joyex__dangxian", "ty_ex__zhiman"}
    for i = 3, 1, -1 do
      if player:hasSkill(choices[i], true) then
        table.removeOne(choices, choices[i])
      end
    end
    if #choices > 0 then
      player:drawCards(1+n, self.name)
      local choice = room:askForChoice(player, choices, self.name, "#joy__zhengnan-choice", true)
      room:handleAddLoseSkills(player, choice, nil)
    else
      player:drawCards(3+n, self.name)
    end
  end,
}
local joy__xiefang = fk.CreateDistanceSkill{
  name = "joy__xiefang",
  correct_func = function(self, from, to)
    if from:hasSkill(self) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p.gender == General.Female then
          n = n + 1
        end
      end
      local m = math.max(n,1)
      return -m
    end
    return 0
  end,
}
local joy__xiefang_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__xiefang_maxcards",
  correct_func = function(self, player)
    if player:hasSkill(self) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p.gender == General.Female then
          n = n + 1
        end
      end
      local m = math.max(n,1)
      return m
    end
    return 0
  end,
}


local joy__wusheng = fk.CreateTriggerSkill{
  name = "joy__wusheng",
  anim_type = "offensive",
  pattern = "slash",
  events = {fk.TurnStart, fk.AfterCardUseDeclared},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return (event == fk.TurnStart) or (data.card.trueName == "slash" and data.card.color == Card.Red)
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, "joy__wusheng", "drawcard")
      local ids = room:getCardsFromPileByRule("slash|.|heart,diamond", 1, "allPiles")
      if #ids > 0 then
        room:obtainCard(player, ids[1], false, fk.ReasonPrey)
      end
    else
      room:notifySkillInvoked(player, "joy__wusheng", "offensive")
      data.additionalDamage = (data.additionalDamage or 0) + 1
    end
  end,
}
joy__xiefang:addRelatedSkill(joy__xiefang_maxcards)
joy__guansuo:addSkill(joy__zhengnan)
joy__guansuo:addSkill(joy__xiefang)
joy__guansuo:addRelatedSkill(joy__wusheng)
joy__guansuo:addRelatedSkill("joyex__dangxian")
joy__guansuo:addRelatedSkill("ty_ex__zhiman")
Fk:loadTranslationTable{
  ["joy__guansuo"] = "关索",
  ["#joy__guansuo"] = "倜傥孑侠",

  ["joy__zhengnan"] = "征南",
  [":joy__zhengnan"] = "每名角色限一次，当一名角色进入濒死状态时，你可以回复1点体力，然后摸一张牌并选择获得下列技能中的一个："..
  "〖武圣〗，〖当先〗和〖制蛮〗（若技能均已获得，则改为摸三张牌），若自己濒死，则回复体力数和摸牌数+1。",
  ["joy__xiefang"] = "撷芳",
  [":joy__xiefang"] = "锁定技，你计算与其他角色的距离-X,你的手牌上限+X（X为全场女性角色数且至少为1）。",
  ["#joy__zhengnan-choice"] = "征南：选择获得的技能",
  ["joy__wusheng"] = "武圣",
  [":joy__wusheng"] = "回合开始时，你获得一张红色【杀】，你的红色【杀】伤害+1。",

  ["$joy__wusheng_joy__guansuo"] = "我敬佩你的勇气。",
  ["$joyex__dangxian_joy__guansuo"] = "时时居先，方可快人一步。",
  ["$ty_ex__zhiman_joy__guansuo"] = "败军之将，自当纳贡！",
}

local joy__huangchengyan = General(extension, "joy__huangchengyan", "qun", 3)
local joy__zecai = fk.CreateTriggerSkill{
  name = "joy__zecai",
  frequency = Skill.Limited,
  events = {fk.RoundEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) < 1
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local player_table = {}
    room.logic:getEventsOfScope(GameEvent.UseCard, 1, function (e)
      local use = e.data[1]
      if use.card.type == Card.TypeTrick then
        local from = use.from
        player_table[from] = (player_table[from] or 0) + 1
      end
    end, Player.HistoryRound)
    local max_time, max_pid = 0, nil
    for pid, time in pairs(player_table) do
      if time > max_time then
        max_pid, max_time = pid, time
      elseif time == max_time then
        max_pid = 0
      end
    end
    local max_p = nil
    if max_pid ~= 0 then
      max_p = room:getPlayerById(max_pid)
    end
    if max_p and not max_p.dead then
      room:setPlayerMark(max_p, "@@joy__zecai_extra", 1)
    end
    local to = room:askForChoosePlayers(player, table.map(room.alive_players,Util.IdMapper), 1, 1, "#joy__zecai-choose", self.name, true)
    if max_p and not max_p.dead then
      room:setPlayerMark(max_p, "@@joy__zecai_extra", 0)
    end
    if #to > 0 then
      self.cost_data = {to[1], max_pid}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data[1])
    if not tar:hasSkill("joyex__jizhi", true) then
      room:addPlayerMark(tar, "joy__zecai_tmpjizhi")
      room:handleAddLoseSkills(tar, "joyex__jizhi", nil, true, false)
    end
    if self.cost_data[1] == self.cost_data[2] then
      tar:gainAnExtraTurn()
    end
  end,

  refresh_events = {fk.RoundEnd},
  can_refresh = function(self, event, target, player, data)
    return player:getMark("joy__zecai_tmpjizhi") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:handleAddLoseSkills(player, "-joyex__jizhi", nil, true, false)
  end,
}
joy__huangchengyan:addSkill("jiezhen")
joy__huangchengyan:addSkill(joy__zecai)
joy__huangchengyan:addSkill("yinshih")
Fk:loadTranslationTable{
  ["joy__huangchengyan"] = "黄承彦",
  ["#joy__huangchengyan"] = "捧月共明",
  
  ["joy__zecai"] = "择才",
  [":joy__zecai"] = "限定技，一轮结束时，你可令一名角色获得〖集智〗直到下一轮结束，然后若其是本轮使用锦囊牌数唯一最多的角色，其执行一个额外的回合。",

  ["#joy__zecai-choose"] = "你可以发动择才，令一名角色获得〖集智〗直到下轮结束",
  ["@@joy__zecai_extra"] = "择才 额外回合",

  ["$joy__zecai1"] = "诸葛良才，可为我佳婿。",
  ["$joy__zecai2"] = "梧桐亭亭，必引凤而栖。",
}


local wanglang = General(extension, "joy__wanglang", "wei", 3)
wanglang:addSkill("ty__gushe")
wanglang:addSkill("ty__jici")
Fk:loadTranslationTable{
  ["joy__wanglang"] = "王朗",
  ["#joy__wanglang"] = "凤鹛",
}

local luotong = General(extension, "joy__luotong", "wu", 3)
luotong:addSkill("renzheng")
luotong:addSkill("jinjian")
Fk:loadTranslationTable{
  ["joy__luotong"] = "骆统",
  ["#joy__luotong"] = "蹇谔匪躬",
}

local caomao = General(extension, "joy__caomao", "wei", 3, 4)
caomao:addSkill("qianlong")
caomao:addSkill("fensi")
caomao:addSkill("juetao")
caomao:addSkill("zhushi")
Fk:loadTranslationTable{
  ["joy__caomao"] = "曹髦",
  ["#joy__caomao"] = "霸业的终耀",
}

local liuzan = General(extension, "joy__liuzan", "wu", 4)
liuzan:addSkill("ty__fenyin")
liuzan:addSkill("liji")
Fk:loadTranslationTable{
  ["joy__liuzan"] = "留赞",
  ["#joy__liuzan"] = "啸天亢声",
}

local puyuan = General(extension, "joy__puyuan", "shu", 4)
puyuan:addSkill("tianjiang")
puyuan:addSkill("zhuren")
Fk:loadTranslationTable{
  ["joy__puyuan"] = "蒲元",
  ["#joy__puyuan"] = "淬炼百兵",
}

local nanhualaoxian = General(extension, "joy__laoxian", "qun", 4)
nanhualaoxian:addSkill("gongxiu")
nanhualaoxian:addSkill("jinghe")
nanhualaoxian:addRelatedSkill("ex__leiji")
nanhualaoxian:addRelatedSkill("yinbingn")
nanhualaoxian:addRelatedSkill("huoqi")
nanhualaoxian:addRelatedSkill("guizhu")
nanhualaoxian:addRelatedSkill("xianshou")
nanhualaoxian:addRelatedSkill("lundao")
nanhualaoxian:addRelatedSkill("guanyue")
nanhualaoxian:addRelatedSkill("yanzhengn")
nanhualaoxian:addRelatedSkill("ex__biyue")
nanhualaoxian:addRelatedSkill("ex__tuxi")
nanhualaoxian:addRelatedSkill("mingce")
nanhualaoxian:addRelatedSkill("zhiyan")
Fk:loadTranslationTable{
  ["joy__laoxian"] = "南华老仙",
  ["#joy__laoxian"] = "仙人指路",
}



local xiahoujie = General(extension, "joy__xiahoujie", "wei", 5)
xiahoujie:addSkill("liedan")
xiahoujie:addSkill("zhuangdan")
Fk:loadTranslationTable{
  ["joy__xiahoujie"] = "夏侯杰",
  ["#joy__xiahoujie"] = "当阳虎胆",
}

local sunyi = General(extension, "joy__sunyi", "wu", 5)
local xiongyis = fk.CreateTriggerSkill{
  name = "joy__xiongyis",
  anim_type = "defensive",
  frequency = Skill.Limited,
  events = {fk.AskForPeaches},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.dying and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = "#xiongyis1-invoke:::"..tostring(math.min(3, player.maxHp))
    if table.find(player.room.alive_players, function(p)
      return p.general == "joy__xushi" or p.deputyGeneral == "joy__xushi" end)
    then
      prompt = "#xiongyis2-invoke"
    end
    if player.room:askForSkillInvoke(player, self.name, nil, prompt) then
      self.cost_data = prompt
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = tonumber(string.sub(self.cost_data, 10, 10))
    if n == 1 then
      local maxHp = player.maxHp
      room:recover({
        who = player,
        num = math.min(3, maxHp) - player.hp,
        recoverBy = player,
        skillName = self.name
      })
      room:changeHero(player, "joy__xushi", false, false, true, false)
    else
      room:recover({
        who = player,
        num = 1 - player.hp,
        recoverBy = player,
        skillName = self.name
      })
      room:handleAddLoseSkills(player, "joy__hunzi", nil, true, false)
    end
  end,
}
local hunzi = fk.CreateTriggerSkill{
  name = "joy__hunzi",
  frequency = Skill.Wake,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and
      player.phase == Player.Start
  end,
  can_wake = function(self, event, target, player, data)
    return player.hp == 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, -1)
    room:handleAddLoseSkills(player, "ex__yingzi|joy__yinghun", nil, true, false)
  end,
}
sunyi:addSkill("jiqiaos")
sunyi:addSkill(xiongyis)
sunyi:addRelatedSkill(hunzi)
sunyi:addRelatedSkill("ex__yingzi")
sunyi:addRelatedSkill("joy__yinghun")
Fk:loadTranslationTable{
  ["joy__sunyi"] = "孙翊",
  ["#joy__sunyi"] = "虓风快意",

  ["joy__xiongyis"] = "凶疑",
  [":joy__xiongyis"] = "限定技，当你处于濒死状态时，若徐氏：不在场，你可以将体力值回复至3点并将武将牌替换为徐氏；"..
  "在场，你可以将体力值回复至1点并获得技能〖魂姿〗。",
  ["joy__hunzi"] = "魂姿",
  [":joy__hunzi"] = "觉醒技，准备阶段，若你的体力为1，你减一点体力上限，然后获得“英姿”和“英魂”",

  ["#xiongyis1-invoke"] = "凶疑：你可以将回复体力至%arg点并变身为徐氏！",
  ["#xiongyis2-invoke"] = "凶疑：你可以将回复体力至1点并获得〖魂姿〗！",

  ["$ex__yingzi_joy__sunyi"] = "骁悍果烈，威震江东！",
}

local xurong = General(extension, "joy__xurong", "qun", 4)
local xionghuo = fk.CreateActiveSkill{
  name = "joy__xionghuo",
  anim_type = "offensive",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:getMark("@joy__baoli") > 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):getMark("@joy__baoli") == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:removePlayerMark(player, "@joy__baoli", 1)
    room:addPlayerMark(target, "@joy__baoli", 1)
  end,
}
local xionghuo_record = fk.CreateTriggerSkill{
  name = "#joy__xionghuo_record",
  main_skill = xionghuo,
  anim_type = "offensive",
  events = {fk.GameStart, fk.DamageCaused, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(xionghuo) then
      if event == fk.GameStart then
        return true
      elseif event == fk.DamageCaused then
        return target == player and data.to ~= player and data.to:getMark("@joy__baoli") > 0
      else
        return target ~= player and target:getMark("@joy__baoli") > 0 and target.phase == Player.Play
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("joy__xionghuo")
    if event == fk.GameStart then
      room:addPlayerMark(player, "@joy__baoli", 3)
    elseif event == fk.DamageCaused then
      room:doIndicate(player.id, {data.to.id})
      data.damage = data.damage + 1
    else
      room:doIndicate(player.id, {target.id})
      room:removePlayerMark(target, "@joy__baoli", 1)
      local n = 3
      if target:isNude() then
        n = 2
      end
      local rand = math.random(1, n)
      if rand == 1 then
        room:damage {
          from = player,
          to = target,
          damage = 1,
          damageType = fk.FireDamage,
          skillName = "joy__xionghuo",
        }
        local mark = target:getTableMark( "joy__xionghuo_prohibit-turn")
        table.insert(mark, player.id)
        room:setPlayerMark(target, "joy__xionghuo_prohibit-turn", mark)

      elseif rand == 2 then
        room:loseHp(target, 1, "joy__xionghuo")
        room:addPlayerMark(target, "MinusMaxCards-turn", 1)
      else
        local dummy = Fk:cloneCard("dilu")
        if not target:isKongcheng() then
          dummy:addSubcard(table.random(target.player_cards[Player.Hand]))
        end
        if #target.player_cards[Player.Equip] > 0 then
          dummy:addSubcard(table.random(target.player_cards[Player.Equip]))
        end
        room:obtainCard(player.id, dummy, false, fk.ReasonPrey)
      end
    end
  end,
}
local xionghuo_prohibit = fk.CreateProhibitSkill{
  name = "#joy__xionghuo_prohibit",
  is_prohibited = function(self, from, to, card)
    return card.trueName == "slash" and table.contains(from:getTableMark( "joy__xionghuo_prohibit-turn") ,to.id)
  end,
}
local shajue = fk.CreateTriggerSkill{
  name = "joy__shajue",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and target.hp < 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:addPlayerMark(player, "@joy__baoli", 1)
    if data.damage and data.damage.card and U.hasFullRealCard(room, data.damage.card) then
      room:obtainCard(player, data.damage.card, true, fk.ReasonPrey)
    end
  end
}
xionghuo:addRelatedSkill(xionghuo_record)
xionghuo:addRelatedSkill(xionghuo_prohibit)
xurong:addSkill(xionghuo)
xurong:addSkill(shajue)
Fk:loadTranslationTable{
  ["joy__xurong"] = "徐荣",
  --其实就是老徐荣

  ["joy__xionghuo"] = "凶镬",
  [":joy__xionghuo"] = "游戏开始时，你获得3个“暴戾”标记。出牌阶段，你可以交给一名其他角色一个“暴戾”标记，你对有此标记的角色造成的伤害+1，"..
  "且其出牌阶段开始时，移去“暴戾”并随机执行一项："..
  "1.受到1点火焰伤害且本回合不能对你使用【杀】；"..
  "2.流失1点体力且本回合手牌上限-1；"..
  "3.你随机获得其一张手牌和一张装备区里的牌。",
  ["joy__shajue"] = "杀绝",
  [":joy__shajue"] = "锁定技，其他角色进入濒死状态时，若其需要超过一张【桃】或【酒】救回，则你获得一个“暴戾”标记，并获得使其进入濒死状态的牌。",
  ["#joy__xionghuo_record"] = "凶镬",
  ["@joy__baoli"] = "暴戾",

}



local chunyuqiong = General(extension, "joy__chunyuqiong", "qun", 4)
chunyuqiong:addSkill("cangchu")
chunyuqiong:addSkill("liangying")
local shishou = fk.CreateTriggerSkill{
  name = "joy__shishou",
  events = { fk.CardUseFinished, fk.Damaged},
  anim_type = "negative",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.CardUseFinished then
        return player:getMark("@cangchu") > 0 and data.card.name == "analeptic"
      else
        return player:getMark("@cangchu") > 0 and data.damageType == fk.FireDamage
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
      room:removePlayerMark(player, "@cangchu")
      room:broadcastProperty(player, "MaxCards")
  end,
}
chunyuqiong:addSkill(shishou)
Fk:loadTranslationTable{
  ["joy__chunyuqiong"] = "淳于琼",
  ["#joy__chunyuqiong"] = "西原右校尉",
  ["joy__shishou"] = "失守",
  [":joy__shishou"] = "锁定技，当你使用【酒】或受到火焰伤害后，你失去1枚“粮”。",
}


local joy__simahui = General(extension, "joy__simahui", "qun", 3)
local doJianjieMarkChange = function (room, player, mark, acquired, proposer)
  local skill = (mark == "@@joy__dragon_mark") and "jjj__huoji&" or "jjj__lianhuan&"
  room:setPlayerMark(player, mark, acquired and 1 or 0)
  if not acquired then skill = "-"..skill end
  room:handleAddLoseSkills(player, skill, nil, false)
  local double_mark = (player:getMark("@@joy__dragon_mark") > 0 and player:getMark("@@joy__phoenix_mark") > 0)
  local yy_skill = double_mark and "jjj__yeyan&" or "-jjj__yeyan&"
  room:handleAddLoseSkills(player, yy_skill, nil, false)
  if acquired then
    proposer:broadcastSkillInvoke("joy__jianjie", double_mark and 3 or math.random(2))
  end
end
local joy__jianjie = fk.CreateActiveSkill{
  name = "joy__jianjie",
  anim_type = "control",
  mute = true,
  can_use = function(self, player)
    return player:getMark("joy__jianjie-turn") == 0 and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  interaction = function()
    return UI.ComboBox {choices = {"joy__dragon_mark_move", "joy__phoenix_mark_move"}}
  end,
  card_num = 0,
  card_filter = Util.FalseFunc,
  target_num = 2,
  target_filter = function(self, to_select, selected)
    if #selected == 2 or not self.interaction.data then return false end
    local to = Fk:currentRoom():getPlayerById(to_select)
    local mark = (self.interaction.data == "joy__dragon_mark_move") and "@@joy__dragon_mark" or "@@joy__phoenix_mark"
    if #selected == 0 then
      return to:getMark(mark) > 0
    else
      return to:getMark(mark) == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:notifySkillInvoked(player, self.name)
    local from = room:getPlayerById(effect.tos[1])
    local to = room:getPlayerById(effect.tos[2])
    local mark = (self.interaction.data == "joy__dragon_mark_move") and "@@joy__dragon_mark" or "@@joy__phoenix_mark"
    doJianjieMarkChange (room, from, mark, false, player)
    doJianjieMarkChange (room, to, mark, true, player)
  end,
}
local jianjie_trigger = fk.CreateTriggerSkill{
  name = "#joy__jianjie_trigger",
  events = {fk.TurnStart, fk.Death},
  main_skill = joy__jianjie,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self) and player:getMark("joy__jianjie-turn") > 0
    else
      return player:hasSkill(self) and (target:getMark("@@joy__dragon_mark") > 0 or target:getMark("@@joy__phoenix_mark") > 0)
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TurnStart then return true end
    local room = player.room
    local gives = {}
    if target:getMark("@@joy__dragon_mark") > 0 then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__dragon_mark") == 0 end)
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__dragon_mark-move::"..target.id, self.name, true)
        if #tos > 0 then
          table.insert(gives, {"@@joy__dragon_mark", tos[1]})
        end
      end
    end
    if target:getMark("@@joy__phoenix_mark") > 0 then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__phoenix_mark") == 0 end)
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__phoenix_mark-move::"..target.id, self.name, true)
        if #tos > 0 then
          table.insert(gives, {"@@joy__phoenix_mark", tos[1]})
        end
      end
    end
    if #gives > 0 then
      self.cost_data = gives
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, "joy__jianjie")
    if event == fk.TurnStart then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__dragon_mark") == 0 end)
      local dra
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__dragon_mark-give", self.name, false)
        if #tos > 0 then
          dra = room:getPlayerById(tos[1])
          doJianjieMarkChange (room, dra, "@@joy__dragon_mark", true, player)
        end
      end
      local pho_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__phoenix_mark") == 0 end)
      table.removeOne(pho_tars, dra)
      if #pho_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(pho_tars, Util.IdMapper), 1, 1, "#joy__phoenix_mark-give", self.name, false)
        if #tos > 0 then
          local pho = room:getPlayerById(tos[1])
          doJianjieMarkChange (room, pho, "@@joy__phoenix_mark", true, player)
        end
      end
    else
      for _, dat in ipairs(self.cost_data) do
        local mark = dat[1]
        local p = room:getPlayerById(dat[2])
        doJianjieMarkChange (room, p, mark, true, player)
      end
    end
  end,

  refresh_events = {fk.TurnStart, fk.EventAcquireSkill},
  can_refresh = function (self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self,true) and target == player
    else
      return target == player and data == self and player.room:getTag("RoundCount")
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local current_event = room.logic:getCurrentEvent()
    if not current_event then return end
    local turn_event = current_event:findParent(GameEvent.Turn, true)
    if not turn_event then return end
    local events = room.logic.event_recorder[GameEvent.Turn] or Util.DummyTable
    for _, e in ipairs(events) do
      local current_player = e.data[1]
      if current_player == player then
        if turn_event.id == e.id then
          room:setPlayerMark(player, "joy__jianjie-turn", 1)
        end
        break
      end
    end
  end,
}
joy__jianjie:addRelatedSkill(jianjie_trigger)
joy__simahui:addSkill(joy__jianjie)

joy__simahui:addSkill("chenghao")
local joy__yinshi = fk.CreateTriggerSkill{
  name = "joy__yinshi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and (data.damageType ~= fk.NormalDamage or (data.card and data.card.type == Card.TypeTrick)) and (player:getMark("@@joy__dragon_mark") == 0 or player:getMark("@@joy__phoenix_mark") == 0) and #player:getEquipments(Card.SubtypeArmor) == 0
  end,
  on_use = Util.TrueFunc,
}
joy__simahui:addSkill(joy__yinshi)
local jjj__lianhuan = fk.CreateActiveSkill{
  name = "jjj__lianhuan&",
  card_num = 1,
  min_target_num = 0,
  can_use = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 3
  end,
  card_filter = function(self, to_select, selected, selected_targets)
    return #selected == 0 and Fk:getCardById(to_select).suit == Card.Club and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected_cards == 1 then
      local card = Fk:cloneCard("iron_chain")
      card:addSubcard(selected_cards[1])
      return card.skill:canUse(Self, card) and card.skill:targetFilter(to_select, selected, selected_cards, card) and
      not Self:prohibitUse(card) and not Self:isProhibited(Fk:currentRoom():getPlayerById(to_select), card)
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if #effect.tos == 0 then
      room:recastCard(effect.cards, player, self.name)
    else
      room:sortPlayersByAction(effect.tos)
      room:useVirtualCard("iron_chain", effect.cards, player, table.map(effect.tos, Util.Id2PlayerMapper), self.name)
    end
  end,
}
Fk:addSkill(jjj__lianhuan)
local jjj__huoji__fireAttackSkill = fk.CreateActiveSkill{
  name = "jjj__huoji__fire_attack_skill",
  prompt = "#fire_attack_skill",
  target_num = 1,
  mod_target_filter = function(_, to_select, _, _, _, _)
    return not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  target_filter = function(self, to_select, selected, _, card)
    if #selected < self:getMaxTargetNum(Self, card) then
      return self:modTargetFilter(to_select, selected, Self.id, card)
    end
  end,
  on_effect = function(self, room, cardEffectEvent)
    local from = room:getPlayerById(cardEffectEvent.from)
    local to = room:getPlayerById(cardEffectEvent.to)
    if to:isKongcheng() then return end
    local showCard = room:askForCard(to, 1, 1, false, self.name, false, ".|.|.|hand", "#fire_attack-show:" .. from.id)[1]
    to:showCards(showCard)
    local suit = Fk:getCardById(showCard):getSuitString()
    local top = room:getNCards(4)
    for i = 4, 1, -1 do
      table.insert(room.draw_pile, 1, top[i])
    end
    local can_throw = table.filter(top, function(id) return Fk:getCardById(id):getSuitString() == suit end)
    local ids , _ = U.askforChooseCardsAndChoice(from, can_throw, {"OK"}, self.name, "#joy__huoji-card", {"Cancel"}, 1, 1, top)
    if #ids == 0 and not from:isKongcheng() then
      ids = room:askForDiscard(from, 1, 1, false, self.name, true,
      ".|.|" .. suit, "#fire_attack-discard:" .. to.id .. "::" .. suit, true)
    end
    if #ids > 0 then
      room:throwCard(ids, self.name, from, from)
      room:damage({
        from = from,
        to = to,
        card = cardEffectEvent.card,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = self.name
      })
    end
  end,
}
jjj__huoji__fireAttackSkill.cardSkill = true
Fk:addSkill(jjj__huoji__fireAttackSkill)
local jjj__huoji = fk.CreateViewAsSkill{
  name = "jjj__huoji&",
  anim_type = "offensive",
  pattern = "fire_attack",
  prompt = "#huoji",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).color == Card.Red and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip 
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("fire_attack")
    card.skillName = self.name
    card:addSubcard(cards[1])
    return card
  end,
  enabled_at_play = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 3
  end,
}
local huoji_trigger = fk.CreateTriggerSkill{
  name = "#jjj__huoji_trigger",
  events = {fk.PreCardEffect},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill("jjj__huoji&") and data.from == player.id and data.card.trueName == "fire_attack"
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local card = data.card:clone()
    local c = table.simpleClone(data.card)
    for k, v in pairs(c) do
      card[k] = v
    end
    card.skill = jjj__huoji__fireAttackSkill
    data.card = card
  end,
}
jjj__huoji:addRelatedSkill(huoji_trigger)
Fk:addSkill(jjj__huoji)
local jjj__yeyan = fk.CreateActiveSkill{
  name = "jjj__yeyan&",
  anim_type = "offensive",
  min_target_num = 1,
  max_target_num = 3,
  min_card_num = 0,
  max_card_num = 4,
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = function(self, to_select, selected)
    return table.contains(Self.player_cards[Player.Hand], to_select) and not Self:prohibitDiscard(Fk:getCardById(to_select))
    and table.every(selected, function (id) return Fk:getCardById(to_select).suit ~= Fk:getCardById(id).suit end)
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected_cards == 4 then
      return #selected < 2
    elseif #selected_cards == 0 then
      return #selected < 3
    else
      return false
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    
    local damageMap = {}
    if #effect.cards == 0 then
      for _, pid in ipairs(effect.tos) do
        damageMap[pid] = 1
      end
    else
      if #effect.tos == 1 then
        local choice = room:askForChoice(player, {"3", "2"}, self.name)
        damageMap[effect.tos[1]] = tonumber(choice)
      else
        local tos = room:askForChoosePlayers(player, effect.tos, 1, 1, "#yeyan-choose", self.name, false)
        damageMap[tos[1]] = 2
        damageMap[tos[1] == effect.tos[1] and effect.tos[2] or effect.tos[1]] = 1
      end
      room:throwCard(effect.cards, self.name, player, player)
      doJianjieMarkChange (room, player, "@@joy__dragon_mark", false, player)
      doJianjieMarkChange (room, player, "@@joy__phoenix_mark", false, player)
      if not player.dead then
        room:loseHp(player, 3, self.name)
      end
    end
    room:sortPlayersByAction(effect.tos)
    for _, pid in ipairs(effect.tos) do
      local to = room:getPlayerById(pid)
      if not to.dead then
        room:damage{
          from = player,
          to = to,
          damage = damageMap[pid],
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
Fk:addSkill(jjj__yeyan)
Fk:loadTranslationTable{
  ["joy__simahui"] = "司马徽",
  ["#joy__simahui"] = "水镜先生",

  ["joy__jianjie"] = "荐杰",
  [":joy__jianjie"] = "①你的第一个回合开始时，你令一名两名角色分别获得“龙印”与“凤印”；②出牌阶段限一次（你的第一个回合除外），或当拥有“龙印”/“凤印”的角色死亡时，你可以转移“龙印”/“凤印”。"..
  "<br><font color='grey'>•拥有 “龙印”/“凤印” 的角色视为拥有技能“火计”/“连环”（均一回合限三次）；"..
  "<br>•同时拥有“龙印”和“凤印”的角色视为拥有技能“业炎”。",
  ["#joy__jianjie_trigger"] = "荐杰",
  ["@@joy__dragon_mark"] = "龙印",
  ["@@joy__phoenix_mark"] = "凤印",
  ["#joy__dragon_mark-give"] = "荐杰：令一名角色获得“龙印”",
  ["#joy__phoenix_mark-give"] = "荐杰：令一名角色获得“凤印”",
  ["#joy__dragon_mark-move"] = "荐杰：令一名角色获得 %dest 的“龙印”",
  ["#joy__phoenix_mark-move"] = "荐杰：令一名角色获得 %dest 的“凤印”",
  ["joy__dragon_mark_move"] = "转移“龙印”",
  ["joy__phoenix_mark_move"] = "转移“凤印”",

  ["joy__yinshi"] = "隐士",
  [":joy__yinshi"] = "锁定技，若你没同时拥有“龙印”和“凤印”且装备区内没有防具牌，防止受到的属性伤害与锦囊牌造成的伤害。",

  ["jjj__lianhuan&"] = "连环",
  [":jjj__lianhuan&"] = "你可以将一张梅花手牌当【铁索连环】使用或重铸（每回合限三次）。",
  ["jjj__huoji&"] = "火计",
  [":jjj__huoji&"] = "每回合限三次，你可以将一张红色手牌当【火攻】使用，你可以观看牌堆顶的4张牌，选择其中一张代替火攻需弃置的牌，其余的牌放回牌堆顶。",
  ["jjj__huoji__fire_attack_skill"] = "火攻",
  ["#jjj__huoji_trigger"] = "火计",
  
  ["jjj__yeyan&"] = "业炎",
  [":jjj__yeyan&"] = "限定技，出牌阶段，你可以选择至多三名角色，你分别对这些角色造成至多共计3点火焰伤害；若你对一名角色分配2点或更多的火焰伤害，你须先弃置四张不同花色的手牌和龙凤印。",
  ["#jjj__yeyan-choose"] = "业炎：选择第%arg点伤害的目标",

}


local zhangfen = General(extension, "joy__zhangfen", "wu", 4)
local wanglu_engine = {{"joy__siege_engine", Card.Spade, 9}}
local wanglu = fk.CreateTriggerSkill{
  name = "joy__wanglu",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.find(player:getEquipments(Card.SubtypeWeapon), function(id) return Fk:getCardById(id).name == "joy__siege_engine" end) then
      player:gainAnExtraPhase(Player.Play)
    else
      local engine = table.find(U.prepareDeriveCards(room, wanglu_engine, "joy__wanglu_engine"), function (id)
        return room:getCardArea(id) == Card.Void
      end)
      if engine and U.canMoveCardIntoEquip(player, engine) then
        for i = 1, 3, 1 do
          room:setPlayerMark(player, "joy__xianzhu"..tostring(i), 0)
        end
        U.moveCardIntoEquip (room, player, engine, self.name, true, player)
      end
    end
  end,
}
local xianzhu_trigger = fk.CreateTriggerSkill{
  name = "#joy__xianzhu_trigger",
  anim_type = "offensive",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card and data.card.trueName == "slash" and
    table.find(player:getEquipments(Card.SubtypeWeapon), function(id) return Fk:getCardById(id).name == "joy__siege_engine" end)
    and (player:getMark("joy__xianzhu1") + player:getMark("joy__xianzhu2") + player:getMark("joy__xianzhu3")) < 5
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choices = {"joy__xianzhu2", "joy__xianzhu3"}
    if player:getMark("joy__xianzhu1") == 0 then
      table.insert(choices, 1, "joy__xianzhu1")
    end
    local choice = room:askForChoice(player, choices, self.name, "#xianzhu-choice")
    room:addPlayerMark(player, choice, 1)
  end,
}
local xianzhu = fk.CreateActiveSkill{
  name = "joy__xianzhu",
  anim_type = "offensive",
  card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return not player:isNude() and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected, targets)
    return #selected == 0 and Fk:getCardById(to_select).sub_type == Card.SubtypeWeapon and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and not Self:isProhibited(Fk:currentRoom():getPlayerById(to_select), Fk:cloneCard("slash"))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:throwCard(effect.cards,self.name,player)
    local use = {
      from = player.id,
      tos = {{target.id}},
      card = Fk:cloneCard("slash"),
      skillName = self.name,
      extraUse = true,
    }
    room:useCard(use)
  end,
}
local chaixie = fk.CreateTriggerSkill{
  name = "joy__chaixie",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      for _, move in ipairs(data) do
        if move.toArea == Card.Void then
          for _, info in ipairs(move.moveInfo) do
            if Fk:getCardById(info.cardId, true).name == "joy__siege_engine" then
              return true
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    for i = 1, 3, 1 do
      n = n + player:getMark("joy__xianzhu"..tostring(i))
      room:setPlayerMark(player, "joy__xianzhu"..tostring(i), 0)
    end
    player:drawCards(n, self.name)
  end,

  refresh_events = {fk.BeforeCardsMove},
  can_refresh = Util.TrueFunc,
  on_refresh = function(self, event, target, player, data)
    local mirror_moves = {}
    local to_void, cancel_move = {},{}
    local no_updata = (player:getMark("joy__xianzhu1") + player:getMark("joy__xianzhu2") + player:getMark("joy__xianzhu3")) == 0
    for _, move in ipairs(data) do
      if move.from == player.id and move.toArea ~= Card.Void then
        local move_info = {}
        local mirror_info = {}
        for _, info in ipairs(move.moveInfo) do
          local id = info.cardId
          if Fk:getCardById(id, true).name == "joy__siege_engine" and info.fromArea == Card.PlayerEquip then
            if no_updata and move.moveReason == fk.ReasonDiscard then
              table.insert(cancel_move, id)
            else
              table.insert(mirror_info, info)
              table.insert(to_void, id)
            end
          else
            table.insert(move_info, info)
          end
        end
        move.moveInfo = move_info
        if #mirror_info > 0 then
          local mirror_move = table.clone(move)
          mirror_move.to = nil
          mirror_move.toArea = Card.Void
          mirror_move.moveInfo = mirror_info
          table.insert(mirror_moves, mirror_move)
        end
      end
    end
    if #cancel_move > 0 then
      player.room:sendLog{ type = "#cancelDismantle", card = cancel_move, arg = "#siege_engine_skill"  }
    end
    if #to_void > 0 then
      table.insertTable(data, mirror_moves)
      player.room:sendLog{ type = "#destructDerivedCards", card = to_void, }
    end
  end,
}
xianzhu:addRelatedSkill(xianzhu_trigger)
zhangfen:addSkill(wanglu)
zhangfen:addSkill(xianzhu)
zhangfen:addSkill(chaixie)
Fk:loadTranslationTable{
  ["joy__zhangfen"] = "张奋",
  ["#joy__zhangfen"] = "御驰大攻",

  ["joy__wanglu"] = "望橹",
  [":joy__wanglu"] = "锁定技，准备阶段，你将【大攻车】置入你的装备区，若你的装备区内已有【大攻车】，则你执行一个额外的出牌阶段。<br>"..
  "<font color='grey'>【大攻车】<br>♠9 装备牌·武器<br /><b>攻击范围</b>：2<br /><b>武器技能</b>：出牌阶段开始时，你可以视为使用一张【杀】(不计次数），"..
  "当此【杀】对目标角色造成伤害后，你弃置其一张牌。若此牌未升级，则防止此牌被弃置。此牌离开装备区时销毁。",
  ["joy__xianzhu"] = "陷筑",
  [":joy__xianzhu"] = "出牌阶段限一次，你可以弃置手中的一张武器牌，然后视为对场上的一名角色使用了一张【杀】（无视距离且不计入次数）。<br>"..
  "当你使用【杀】造成伤害后，你可以升级【大攻车】（每个【大攻车】最多升级5次）。升级选项：<br>"..
  "【大攻车】的【杀】无视距离和防具（装备【大攻车】以后的所有杀）；<br>【大攻车】的【杀】可指定目标+1；<br>【大攻车】的【杀】造成伤害后弃牌数+1。",
  ["joy__chaixie"] = "拆械",
  [":joy__chaixie"] = "锁定技，当【大攻车】销毁后，你摸X张牌（X为该【大攻车】的升级次数）。",
  ["#joy__xianzhu-choice"] = "陷筑：选择【大攻车】使用【杀】的增益效果",
  ["joy__xianzhu1"] = "无视距离和防具",
  ["joy__xianzhu2"] = "可指定目标+1",
  ["joy__xianzhu3"] = "造成伤害后弃牌数+1",
  ["#joy__xianzhu_trigger"] = "陷筑",

  ["$joy__wanglu1"] = " ",
  ["$joy__wanglu2"] = " ",
  ["$joy__xianzhu1"] = " ",
  ["$joy__xianzhu2"] = " ",
  ["$joy__chaixie1"] = " ",
  ["$joy__chaixie2"] = " ",
  ["~joy__zhangfen"] = " ",
}

local chengyu = General(extension, "joy__chengyu", "wei", 3)
local shefu = fk.CreateTriggerSkill{
  name = "joy__shefu",
  anim_type = "control",
  derived_piles = "joy__shefu",
  events ={fk.EventPhaseStart, fk.Damaged,fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Finish and not player:isNude()
      elseif event == fk.Damaged then
        return target == player and not player:isNude()
      else
        return target ~= player and player.phase == Player.NotActive and data.card.type ~= Card.TypeEquip and U.IsUsingHandcard(target, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart or event == fk.Damaged then
      local cards = room:askForCard(player, 1, 1, true, self.name, true, ".", "#joy__shefu-cost")
      if #cards > 0 then
        self.cost_data = cards[1]
        return true
      end
    else
      local index
      local mark = player:getTableMark( self.name)
      for i = 1, #mark, 1 do
        if data.card.trueName == mark[i][2] then
          index = i
          break
        end
      end
      if index and room:askForSkillInvoke(player, self.name, nil, "#joy__shefu-invoke::"..target.id..":"..data.card.name) then
        self.cost_data = index
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart or event == fk.Damaged then
      player:addToPile(self.name, self.cost_data, false, self.name)
      local names = {}
      local mark = player:getTableMark( self.name)
      for _, id in ipairs(Fk:getAllCardIds()) do
        local card = Fk:getCardById(id)
        if card.type ~= Card.TypeEquip then
          table.insertIfNeed(names, card.trueName)
        end
      end
      if #names > 0 then
        local name = room:askForChoice(player, names, self.name)
        table.insert(mark, {self.cost_data, name})
        room:setPlayerMark(player, self.name, mark)
      end
    else
      local index = self.cost_data
      local mark = player:getTableMark( self.name)
      local throw = mark[index][1]
      table.remove(mark, index)
      room:setPlayerMark(player, self.name, mark)
      if target.phase ~= Player.NotActive then
        room:setPlayerMark(target, "@@joy__shefu-turn", 1)
      end
      room:moveCards({
        from = player.id,
        ids = {throw},
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonPutIntoDiscardPile,
        skillName = self.name,
        specialName = self.name,
      })
      data.tos = {}
      room:sendLog{ type = "#CardNullifiedBySkill", from = target.id, arg = self.name, arg2 = data.card:toLogString() }
    end
  end,
}
local shefu_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__shefu_invalidity",
  invalidity_func = function(self, from, skill)
    return from:getMark("@@joy__shefu-turn") > 0 and not skill.attached_equip and not skill.name:endsWith("&")
  end
}
shefu:addRelatedSkill(shefu_invalidity)
chengyu:addSkill(shefu)
local benyu = fk.CreateTriggerSkill{
  name = "joy__benyu",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from and not data.from.dead
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if room:askForSkillInvoke(player,self.name) then
      local choices = {}
      if not player:isKongcheng() then
        table.insert(choices,"joy__benyu-damage::"..data.from.id)
      end
      local x = math.min(data.from:getHandcardNum(), 5)
      if player:getHandcardNum() < x  then
        table.insert(choices,"joy__benyu-drawcards:::"..x)
      end
      if #choices > 0 then
        local choice = room:askForChoice(player,choices,self.name,"#joy__benyu-ask")
        if choice == "joy__benyu-damage::"..data.from.id then
          local card = room:askForCard(player,1,1,false,self.name,true,".","#joy__benyu-damage::"..data.from.id)
          if #card > 0 then
            self.cost_data = {choice,card}
            return true
          end
        elseif choice == "joy__benyu-drawcards:::"..x then
            self.cost_data = {choice}
            return true
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data[1] == "joy__benyu-damage::"..data.from.id then
      player.room:throwCard(self.cost_data[2], self.name, player, player)
      player.room:damage{
        from = player,
        to = data.from,
        damage = 1,
        skillName = self.name,
      }
    else
      player:drawCards(math.min(5, data.from:getHandcardNum()) - player:getHandcardNum())
    end
  end,
}
chengyu:addSkill(benyu)
Fk:loadTranslationTable{
  ["joy__chengyu"] = "程昱",
  ["#joy__chengyu"] = "泰山捧日",

  ["joy__shefu"] = "设伏",
  [":joy__shefu"] = "①结束阶段和受到伤害后，你可以记录一个基本牌或锦囊牌的牌名并扣置一张牌，称为“伏兵”；<br>"..
  "②当其他角色于你回合外使用手牌时，你可以移去一张记录牌名相同的“伏兵”，令此牌无效（若此牌有目标角色则改为取消所有目标），然后若此时是该角色的回合内，其本回合所有技能失效。",
  ["joy__benyu"] = "贲育",
  [":joy__benyu"] = "当你受到伤害后，你可以选择一项：1.将手牌摸至与伤害来源相同（最多摸至5张）；2.弃置1张牌，然后对伤害来源造成1点伤害。",
  ["#joy__shefu-cost"] = "设伏：你可以将一张牌扣置为“伏兵”",
  ["#joy__benyu-damage"] = "贲育：选择弃置一张手牌，对 %dest 造成1点伤害",
  ["joy__benyu-drawcards"] = "摸至 %arg 张牌",
  ["joy__benyu-damage"] = "弃一张牌对 %dest 造成1点伤害",
  ["@@joy__shefu-turn"] = "设伏封技",
  ["#joy__shefu-invoke"] = "设伏：可以令 %dest 使用的 %arg 无效",
  ["#CardNullifiedBySkill"] = "由于 %arg 的效果，%from 使用的 %arg2 无效",
  ["#joy__benyu-ask"] = "贲育",

  ["$joy__shefu1"] = " ",
  ["$joy__shefu2"] = " ",
  ["$joy__benyu1"] = " ",
  ["$joy__benyu2"] = " ",
  ["~joy__chengyu"] = " ",
}

local longfeng = General(extension, "joy__wolongfengchu", "shu", 4)
local joy__youlong = fk.CreateViewAsSkill{
  name = "joy__youlong",
  switch_skill_name = "joy__youlong",
  anim_type = "switch",
  pattern = ".",
  prompt = function ()
    return "#joy__youlong-prompt"..Self:getSwitchSkillState("joy__youlong")
  end,
  interaction = function()
    local names = {}
    local mark = Self:getTableMark( "@$joy__youlong")
    local isYang = Self:getSwitchSkillState("joy__youlong") == fk.SwitchYang
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if ((card.type == Card.TypeBasic and not isYang) or
        (card:isCommonTrick() and isYang)) and
        not card.is_derived and
        ((Fk.currentResponsePattern == nil and Self:canUse(card)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card))) then
        if not table.contains(mark, card.trueName) then
          table.insertIfNeed(names, card.name)
        end
      end
    end
    if #names == 0 then return end
    return UI.ComboBox {choices = names}
  end,
  card_filter = function (self, to_select, selected)
    return Self:getSwitchSkillState("joy__youlong") == fk.SwitchYin and #selected == 0
    and Fk:getCardById(to_select).type ~= Card.TypeBasic and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  view_as = function(self, cards)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    if Self:getSwitchSkillState("joy__youlong") == fk.SwitchYin then
      if #cards ~= 1 then return end
      card:setMark("joy__youlong_card", cards[1])
    end
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    local mark = player:getTableMark( "@$joy__youlong")
    table.insert(mark, use.card.trueName)
    room:setPlayerMark(player, "@$joy__youlong", mark)
    local state = player:getSwitchSkillState(self.name, true, true)
    room:setPlayerMark(player, "joy__youlong_" .. state .. "-turn", 1)
    if state == "yin" then
      local id = use.card:getMark("joy__youlong_card")
      if id ~= 0 then
        room:throwCard(id, self.name, player, player)
      end
    else
      local choices = player:getAvailableEquipSlots()
      if #choices == 0 then return end
      local choice = room:askForChoice(player, choices, self.name, "#joy__youlong-choice", false, player.equipSlots)
      room:abortPlayerArea(player, choice)
    end
  end,
  enabled_at_play = function(self, player)
    local state = player:getSwitchSkillState(self.name, false, true)
    if player:getMark("joy__youlong_" .. state .. "-turn") == 0 or player:getMark("joy__youlong_levelup") > 0 then
      return state == "yin" or#player:getAvailableEquipSlots() > 0
    end
  end,
  enabled_at_response = function(self, player, response)
    if response then return end
    local state = player:getSwitchSkillState(self.name, false, true)
    local pat = state == "yin" and "basic" or "trick"
    if Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):matchExp(".|0|nosuit|none|.|"..pat) then
      if player:getMark("joy__youlong_" .. state .. "-turn") == 0 or player:getMark("joy__youlong_levelup") > 0 then
        return state == "yin" or#player:getAvailableEquipSlots() > 0
      end
    end
  end,
}
local joy__luanfeng = fk.CreateTriggerSkill{
  name = "joy__luanfeng",
  frequency = Skill.Limited,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.maxHp >= player.maxHp and target.dying
    and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__luanfeng-invoke:"..target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:recover {
      who = target,
      num = 3 - target.hp,
      recoverBy = player,
      skillName = self.name,
    }
    local targets = {player}
    table.insertIfNeed(targets, target)
    for _, p in ipairs(targets) do
      if not p.dead then
        local slots = table.simpleClone(p.sealedSlots)
        table.removeOne(slots, Player.JudgeSlot)
        if #slots > 0 then
          room:resumePlayerArea(p, slots)
        end
      end
    end
    if not target.dead then
      local n = 6 - target:getHandcardNum()
      if n > 0 then
        target:drawCards(n, self.name)
      end
    end
    if player.dead then return end
    room:setPlayerMark(player, "joy__youlong_levelup", 1)
    room:setPlayerMark(player, "@$joy__youlong", 0)
  end,
}
longfeng:addSkill(joy__youlong)
longfeng:addSkill(joy__luanfeng)
Fk:loadTranslationTable{
  ["joy__wolongfengchu"] = "卧龙凤雏",
  ["#joy__wolongfengchu"] = "一匡天下",

  ["joy__youlong"] = "游龙",
  [":joy__youlong"] = "转换技，每回合各限一次，阳：你可以废除一个装备栏，视为使用一张未以此法使用过的普通锦囊牌；阴：你可以弃置一张非基本牌，视为使用一张未以此法使用过的基本牌。",
  ["joy__luanfeng" ] = "鸾凤",
  [":joy__luanfeng"] = "限定技，当一名角色进入濒死状态时，若其体力上限不小于你，" ..
  "你可令其将体力回复至3点，恢复你与其被废除的装备栏，令其手牌补至六张，" ..
  "然后去除〖游龙〗的回合次数限制，重置〖游龙〗使用过的牌名。",

  ["#joy__youlong-prompt0"] = "游龙：废除一个装备栏，视为使用一张未以此法使用过的普通锦囊牌",
  ["#joy__youlong-prompt1"] = "游龙：弃置一张非基本牌，视为使用一张未以此法使用过的基本牌",
  ["#joy__youlong-choice"] = "游龙: 请选择废除一个装备栏",
  ["@$joy__youlong"] = "游龙",
  ["#joy__luanfeng-invoke"] = "鸾凤：你可令 %src 将体力回复至3点，手牌补至六张",

  ['@$joy__youlong'] = '游龙',
  ['$joy__youlong1'] = '',
  ['$joy__youlong2'] = '',
  ['$joy__luanfeng1'] = '',
  ['$joy__luanfeng2'] = '',
  ['~joy__wolongfengchu'] = '',
}

local zhanglu = General(extension, "joy__zhanglu", "qun", 3)
local yishe = fk.CreateTriggerSkill{
  name = "joy__yishe",
  anim_type = "support",
  derived_piles = "joy__zhanglu_mi",
  events = {fk.EventPhaseStart, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Finish 
      else
        if #player:getPile("joy__zhanglu_mi") == 0 and player:isWounded() then
          for _, move in ipairs(data) do
            if move.from == player.id then
              for _, info in ipairs(move.moveInfo) do
                if info.fromSpecialName == "joy__zhanglu_mi" then
                  return true
                end
              end
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__yishe-invoke")
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      player:drawCards(2, self.name)
      if player:isNude() then return end
      local dummy = Fk:cloneCard("dilu")
      local cards
      if #player:getCardIds("he") < 3 then
        cards = player:getCardIds("he")
      else
        cards = room:askForCard(player, 2, 2, true, self.name, false, ".", "#joy__yishe-cost")
      end
      dummy:addSubcards(cards)
      player:addToPile("joy__zhanglu_mi", dummy, true, self.name)
    else
      room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name
      })
    end
  end,
}
local bushi = fk.CreateTriggerSkill{
  name = "joy__bushi",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:hasSkill("joy__yishe") and (target == player or data.from == player) and #player:getPile("joy__zhanglu_mi") > 0 and not (data.from.dead or data.to.dead)
  end,
  on_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      self.cancel_cost = false
      for i = 1, data.damage do
        if #player:getPile("joy__zhanglu_mi") == 0 or self.cancel_cost then return end
        self:doCost(event, target, player, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local x
    if target == player then
      x = "#joy__bushi-get"
    else 
      x = "#joy__bushi-give::"..target.id
    end
    if player.room:askForSkillInvoke(player, self.name, data,x) then
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if #player:getPile("joy__zhanglu_mi") == 1 then
      room:obtainCard(target, player:getPile("joy__zhanglu_mi")[1], true, fk.ReasonPrey)
    else
      room:fillAG(player, player:getPile("joy__zhanglu_mi"))
      local id = room:askForAG(player, player:getPile("joy__zhanglu_mi"), false, self.name)
      room:closeAG(player)
      room:obtainCard(target, id, true, fk.ReasonPrey)
    end
  end,
}
local midao = fk.CreateTriggerSkill{
  name = "joy__midao",
  anim_type = "control",
  expand_pile = "joy__zhanglu_mi",
  events = {fk.AskForRetrial},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and #player:getPile("joy__zhanglu_mi") > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local card = room:askForCard(player, 1, 1, false, self.name, true, ".|.|.|joy__zhanglu_mi|.|.", "#joy__midao-choose::" .. target.id, "joy__zhanglu_mi")
    if #card > 0 then
      self.cost_data = card[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:retrial(Fk:getCardById(self.cost_data), player, data, self.name)
    if not player.dead then
      player:drawCards(1,self.name)
    end
  end,
}
zhanglu:addSkill(yishe)
zhanglu:addSkill(bushi)
zhanglu:addSkill(midao)
Fk:loadTranslationTable{
  ["joy__zhanglu"] = "张鲁",
  ["#joy__zhanglu"] = "政宽教惠",
  ["joy__yishe"] = "义舍",
  [":joy__yishe"] = "结束阶段开始时，你可以摸两张牌，然后将两张牌置于武将牌上，称为“米”。当“米”移至其他区域后，"..
  "若你的武将牌上没有“米”，你回复1点体力。",
  ["joy__bushi"] = "布施",
  [":joy__bushi"] = "当你受到1点伤害后，若你拥有技能“义舍”，你可获得一张“米”；当你对其他角色造成1点伤害后，你可以交给其一张“米”。",
  ["joy__midao"] = "米道",
  [":joy__midao"] = "当一张判定牌生效前，你可以打出一张“米”代替之,然后你摸一张牌",
  ["joy__zhanglu_mi"] = "米",
  ["#joy__yishe-invoke"] = "义舍：你可以摸两张牌，然后将两张牌置为“米”",
  ["#joy__yishe-cost"] = "义舍：将两张牌置为“米”",
  ["#joy__bushi-get"] = "布施：是否获取一张“米”",
  ["#joy__bushi-give"] = "布施：是否交给 %dest 一张“米”",
  ["#joy__midao-choose"] = "米道：你可以打出一张“米”修改 %dest 的判定，然后摸一张牌",

  ["$joy__yishe1"] = " ",
  ["$joy__yishe2"] = " ",
  ["$joy__bushi1"] = " ",
  ["$joy__bushi2"] = " ",
  ["$joy__midao1"] = " ",
  ["$joy__midao2"] = " ",
  ["~zhanglu"] = " ",
}


local zhouxuan = General(extension, "joy__zhouxuan", "wei", 3)
local wumei = fk.CreateTriggerSkill{
  name = "joy__wumei",
  anim_type = "support",
  events = {fk.BeforeTurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(table.filter(room.alive_players, function (p)
      return p:getMark("@@joy__wumei_extra") == 0 end), Util.IdMapper), 1, 1, "#joy__wumei-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:addPlayerMark(to, "@@joy__wumei_extra", 1)
    local hp_record = {}
    for _, p in ipairs(room.alive_players) do
      table.insert(hp_record, {p.id, p.hp})
    end
    room:setPlayerMark(to, "joy__wumei_record", hp_record)
    to:gainAnExtraTurn()
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@@joy__wumei_extra") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@@joy__wumei_extra", 0)
    room:setPlayerMark(player, "joy__wumei_record", 0)
  end,
}
local wumei_delay = fk.CreateTriggerSkill{
  name = "#joy__wumei_delay",
  events = {fk.EventPhaseStart},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return player == target and player.phase == Player.Finish and player:getMark("@@joy__wumei_extra") > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, wumei.name, "special")
    local hp_record = player:getMark("joy__wumei_record")
    if type(hp_record) ~= "table" then return false end
    for _, p in ipairs(room:getAlivePlayers()) do
      local p_record = table.find(hp_record, function (sub_record)
        return #sub_record == 2 and sub_record[1] == p.id
      end)
      if p_record then
        p.hp = math.min(p.maxHp, p_record[2])
        room:broadcastProperty(p, "hp")
      end
    end
  end,
}
local zhanmeng = fk.CreateTriggerSkill{
  name = "joy__zhanmeng",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local room = player.room
      local mark = player:getMark("joy__zhanmeng_last-turn")
      if type(mark) ~= "table" then
        mark = {}
        local logic = room.logic
        local current_event = logic:getCurrentEvent()
        local all_turn_events = logic.event_recorder[GameEvent.Turn]
        if type(all_turn_events) == "table" then
          local index = #all_turn_events
          if index > 0 then
            local turn_event = current_event:findParent(GameEvent.Turn)
            if turn_event ~= nil then
              index = index - 1
            end
            if index > 0 then
              current_event = all_turn_events[index]
              current_event:searchEvents(GameEvent.UseCard, 1, function (e)
                table.insertIfNeed(mark, e.data[1].card.trueName)
                return false
              end)
            end
          end
        end
        room:setPlayerMark(player, "joy__zhanmeng_last-turn", mark)
      end
      return (player:getMark("joy__zhanmeng1-turn") == 0 and not table.contains(mark, data.card.trueName)) or
        player:getMark("joy__zhanmeng2-turn") == 0 or (player:getMark("joy__zhanmeng3-turn") == 0 and
        not table.every(room.alive_players, function (p)
          return p == player or p:isNude()
        end))
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("joy__zhanmeng_last-turn")
    local choices = {}
    self.cost_data = {}
    if player:getMark("joy__zhanmeng1-turn") == 0 and not table.contains(mark, data.card.trueName) then
      table.insert(choices, "joy__zhanmeng1")
    end
    if player:getMark("joy__zhanmeng2-turn") == 0 then
      table.insert(choices, "joy__zhanmeng2")
    end
    local targets = {}
    if player:getMark("joy__zhanmeng3-turn") == 0 then
      for _, p in ipairs(room.alive_players) do
        if p ~= player and not p:isNude() then
          table.insertIfNeed(choices, "joy__zhanmeng3")
          table.insert(targets, p.id)
        end
      end
    end
    table.insert(choices, "Cancel")
    local choice = room:askForChoice(player, choices, self.name, "#joy__zhanmeng-choice", false,
    {"joy__zhanmeng1", "joy__zhanmeng2", "joy__zhanmeng3", "Cancel"})
    if choice == "Cancel" then return false end
    self.cost_data[1] = choice
    if choice == "joy__zhanmeng3" then
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#joy__zhanmeng-choose", self.name, true)
      if #to > 0 then
        self.cost_data[2] = to[1]
      else
        return false
      end
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = self.cost_data[1]
    room:setPlayerMark(player, choice.."-turn", 1)
    if choice == "joy__zhanmeng1" then
      local cards = {}
      for _, id in ipairs(room.draw_pile) do
        if not Fk:getCardById(id).is_damage_card then
          table.insertIfNeed(cards, id)
        end
      end
      if #cards > 0 then
        local card = table.random(cards)
        room:moveCards({
          ids = {card},
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        })
      end
    elseif choice == "joy__zhanmeng2" then
      room:setPlayerMark(player, "joy__zhanmeng_delay-turn", data.card.trueName)
    elseif choice == "joy__zhanmeng3" then
      local p = room:getPlayerById(self.cost_data[2])
      local cards = room:askForDiscard(p, 2, 2, true, self.name, false, ".", "#joy__zhanmeng-discard:"..player.id)
      local x = Fk:getCardById(cards[1]).number
      if #cards == 2 then
        x = x + Fk:getCardById(cards[2]).number
      end
      if x > 10 and not p.dead then
        room:damage{
          from = player,
          to = p,
          damage = 1,
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = Util.TrueFunc,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@joy__zhanmeng_delay", player:getMark("joy__zhanmeng_delay-turn"))
  end,
}
local zhanmeng_delay = fk.CreateTriggerSkill{
  name = "#joy__zhanmeng_delay",
  anim_type = "drawcard",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return player:usedSkillTimes(self.name) == 0 and player:getMark("@joy__zhanmeng_delay") == data.card.trueName
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    for _, id in ipairs(room.draw_pile) do
      if Fk:getCardById(id).is_damage_card then
        table.insertIfNeed(cards, id)
      end
    end
    if #cards > 0 then
      local card = table.random(cards)
      room:moveCards({
        ids = {card},
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        proposer = player.id,
        skillName = self.name,
      })
    end
  end,
}
wumei:addRelatedSkill(wumei_delay)
zhanmeng:addRelatedSkill(zhanmeng_delay)
zhouxuan:addSkill(wumei)
zhouxuan:addSkill(zhanmeng)
Fk:loadTranslationTable{
  ["joy__zhouxuan"] = "周宣",
  ["#joy__zhouxuan"] = "夜华青乌",

  ["joy__wumei"] = "寤寐",
  [":joy__wumei"] = "每轮限一次，回合开始前，你可以令一名角色执行一个额外的回合：该回合结束时，将所有存活角色的体力值调整为此额外回合开始时的数值。",
  ["joy__zhanmeng"] = "占梦",
  [":joy__zhanmeng"] = "你使用牌时，可以执行以下一项（每回合每项各限一次）：<br>"..
  "1.上一回合内，若没有同名牌被使用，你获得一张非伤害牌。<br>"..
  "2.下一回合内，当同名牌首次被使用后，你获得一张伤害牌。<br>"..
  "3.令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害。",
  ["#joy__wumei-choose"] = "寤寐: 你可以令一名角色执行一个额外的回合",
  ["#joy__wumei_delay"] = "寤寐",
  ["@@joy__wumei_extra"] = "寤寐",
  ["joy__zhanmeng1"] = "你获得一张非伤害牌",
  ["joy__zhanmeng2"] = "下一回合内，当同名牌首次被使用后，你获得一张伤害牌",
  ["joy__zhanmeng3"] = "令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害",
  ["#joy__zhanmeng_delay"] = "占梦",
  ["@joy__zhanmeng_delay"] = "占梦",
  ["#joy__zhanmeng-choice"] = "是否发动 占梦，选择一项效果",
  ["#joy__zhanmeng-choose"] = "占梦: 令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害",
  ["#joy__zhanmeng-discard"] = "占梦：弃置2张牌，若点数之和大于10，%src 对你造成1点火焰伤害",

  ["$joy__wumei1"] = "大梦若期，皆付一枕黄粱。",
  ["$joy__wumei2"] = "日所思之，故夜所梦之。",
  ["$joy__zhanmeng1"] = "梦境缥缈，然有迹可占。",
  ["$joy__zhanmeng2"] = "万物有兆，唯梦可卜。",
  ["~joy__zhouxuan"] = "人生如梦，假时亦真。",
}

return extension